package com.specter.dev.code.execute;

import static com.specter.utils.StringUtils.cap_first;
import static com.specter.utils.StringUtils.fix;
import static com.specter.utils.StringUtils.toJavaName;

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.specter.dev.code.builder.GenConfiguration.ModuleInput;
import com.specter.utils.JDBCUtils;

/**
 * Note:通过读取数据库数据表完成实体搜索 <br/>
 * <br/>
 * <b> &lt;input type="database" src="jdbc:mysql://localhost:3306/test|root|sa"
 * tgt="a,b" fix="-IDS_%s+_ENTITY" /&gt; </b>
 * 
 * @author Liang.Wang
 * @version Mar 23, 2017
 */
public class ModuleInputExe4Database implements ModuleInputExe {

	@Override
	public List<?> input(ModuleInput input) {
		List<ModuleInputExe.Entity> list = new ArrayList<>();
		Connection con = null;
		try {
			con = JDBCUtils.getConnection(input.getSrc());
			con.setClientInfo("remarks", "true");
			con.setClientInfo("useInformationSchema", "true");

			//catalog为null是查所有库中表
			ResultSet trs = con.getMetaData().getTables(null, "%", input.getTgt(), new String[] { "TABLE" });
			while (trs.next()) {
				ModuleInputExe.Entity entity = new ModuleInputExe.Entity();
				entity.setTableName(trs.getString("TABLE_NAME"));
				entity.setTableSchema(trs.getString("TABLE_CAT")); // TABLE_SCHEM
				entity.setTableRemark(trs.getString("REMARKS"));
				entity.setEntityName(cap_first(toJavaName(fix(input.getFix(), entity.getTableName()))));
				entity.setClassName(null);// 还未确定生成的路径
				entity.setProperties(new ArrayList<>());

				// 查找主键的列
				ResultSet krs = con.getMetaData().getPrimaryKeys(null, entity.getTableSchema(), entity.getTableName());
				String key = krs.next() ? krs.getString("COLUMN_NAME") : null;// 只取一个KEY
				JDBCUtils.release(krs);

				ResultSet crs = con.getMetaData().getColumns(null, entity.getTableSchema(), entity.getTableName(), "%");
				while (crs.next()) {
					ModuleInputExe.EntityProperty property = new ModuleInputExe.EntityProperty();
					property.setColumn(crs.getString("COLUMN_NAME"));
					property.setType(crs.getString("TYPE_NAME"));
					property.setRemark(crs.getString("REMARKS"));

					property.setName(toJavaName(property.getColumn()));
					property.setClazz(this.clazz(crs.getObject("DATA_TYPE")));

					if (property.getColumn().equals(key)) {
						entity.setId(property);
					} else {
						entity.getProperties().add(property);
					}
				}
				JDBCUtils.release(crs);
				list.add(entity);
			}
			JDBCUtils.release(trs);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtils.release(con);
		}
		return list;
	}

	private Map<Object, String> types = new HashMap<Object, String>() {
		private static final long serialVersionUID = 1L;

		{
			put(java.sql.Types.VARCHAR, "String");
			put(java.sql.Types.INTEGER, "Long");
			put(java.sql.Types.SMALLINT, "Integer");
			put(java.sql.Types.TINYINT, "Integer");
			put(java.sql.Types.DATE, "java.util.Date");
			put(java.sql.Types.TIME, "java.util.Date");
			put(java.sql.Types.TIMESTAMP, "java.util.Date");
		}
	};

	private String clazz(Object typeKey) {
		String type = types.get(typeKey);
		return type == null ? "String" : type;
	}

}
